package fun.stgoder.easydarwin.jobs.bl.executor;

import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fun.stgoder.easydarwin.jobs.bl.BL;
import fun.stgoder.easydarwin.jobs.comm.Constants;

public enum CleanupExecutor {

    INSTANCE;

    private final Logger logger = LoggerFactory.getLogger(CleanupExecutor.class);

    private ExecutorService executor;

    {
        int processors = Runtime.getRuntime().availableProcessors();
        executor = new ThreadPoolExecutor(processors * 2, // core size
                processors * 2 * 2, 60L, TimeUnit.SECONDS, // maximum size
                new LinkedBlockingQueue<Runnable>(128), // task queue size
                Executors.defaultThreadFactory(), // thread factory
                new RejectedExecutionHandler() { // reject policy
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { // abort direct
                        if (Constants.TEST_MODE)
                            logger.info("discard");
                    }
                });
    }

    public class CleanupTask implements Runnable {

        private final Logger logger = LoggerFactory.getLogger(CleanupTask.class);

        @Override
        public void run() {
            try {

                if (Constants.TEST_MODE)
                    logger.info("cleanup ts files");

                try {

                    File m3u8Dir = new File(Constants.EASYDARWIN_M3U8_PATH);
                    File[] streamM3u8Dirs = m3u8Dir.listFiles();

                    for (File streamM3u8Dir : streamM3u8Dirs) {

                        /*
                         * String path = streamM3u8Dir.getName(); boolean recording =
                         * BL.JOB.streamHasActiveJobs(path); if (recording) { continue; } else {
                         */

                        try {
                            File currentWorkingM3u8Dir = BL.getCurrentWorkingM3u8Dir(streamM3u8Dir.getName());
                            if (currentWorkingM3u8Dir != null) {
                                if (Constants.TEST_MODE)
                                    logger.info("cleanup dir: " + streamM3u8Dir.getName() + "/"
                                            + currentWorkingM3u8Dir.getName());

                                File[] tsFiles = currentWorkingM3u8Dir.listFiles();
                                for (File tsFile : tsFiles) {
                                    if (tsFile.isFile() && tsFile.getName().endsWith(Constants.RECORD_FILE_SUFFIX)) { // is
                                        // ts
                                        // file
                                        if (tsFile.lastModified() < System.currentTimeMillis() - Constants.TS_EXPIRE) {
                                            tsFile.delete();
                                        }
                                    }
                                }
                            }
                        } catch (Exception e) {
                            logger.error(e.getMessage());
                        }

                    }

                } catch (Exception e) {
                    logger.error(e.getMessage());
                }
            } catch (Exception e) {
                if (Constants.TEST_MODE) {
                    logger.error("cleanup ts file in executor", e);
                } else {
                    logger.error("cleanup ts file in executor: " + e.getMessage());
                }
            }
        }

    }

    public void execute() {
        if (Constants.PRE_RECORD)
            executor.execute(new CleanupTask());
    }
}
